\subsection{Использование IMUL вместо MUL}
\label{IMUL_over_MUL}

\myindex{x86!\Instructions!MUL}
\myindex{x86!\Instructions!IMUL}
В примере вроде \lstref{unsigned_multiply_C} где умножаются два беззнаковых значения, компилируется в
\lstref{unsigned_multiply_lst}, где используется \IMUL вместо \MUL.

Это важное свойство обоих инструкций: \MUL и \IMUL{}.
Прежде всего, они обе выдают 64-битное значение если перемножаются два 32-битных, либо же 128-битное значение,
если перемножаются два 64-битных (максимальное возможное \glslink{product}{произведение} в 32-битное среде это \\
\GTT{0xffffffff*0xffffffff=0xfffffffe00000001}).
Но в стандарте \CCpp нет способа доступиться к старшей половине результата, а \glslink{product}{произведение} всегда имеет
тот же размер, что и множители. % TODO \gls{}?
И обе инструкции \MUL и \IMUL работают одинаково, если старшая половина результата игнорируется, т.е., обе инструкции
генерируют одинаковую младшую половину.
Это важное свойство способа представления знаковых чисел \q{дополнительный код}.

Так что компилятор с \CCpp может использовать любую из этих инструкций.

Но \IMUL более гибкая чем \MUL, потому что она может брать любой регистр как вход, в то время как \MUL требует,
чтобы один из множителей находился в регистре \AX/\EAX/\RAX.
И даже более того: \MUL сохраняет результат в паре \GTT{EDX:EAX} в 32-битной среде, либо в \GTT{RDX:RAX} в 64-битной,
так что она всегда вычисляет полный результат.
И напротив, в \IMUL можно указать единственный регистр назначения вместо пары, тогда \ac{CPU} будет вычислять только
младшую половину, а это быстрее
[см. Torborn Granlund, \IT{Instruction latencies and throughput for AMD and Intel x86 processors}\footnote{\url{http://yurichev.com/mirrors/x86-timing.pdf}]}).

Учитывая это, компиляторы \CCpp могут генерировать инструкцию \IMUL чаще, чем \MUL.

\myindex{Compiler intrinsic}
Тем не менее, используя \IT{compiler intrinsic}, можно произвести беззнаковое умножение и получить \IT{полный} результат.
Иногда это называется \IT{расширенное умножение} (\IT{extended multiplication}).
MSVC для этого имеет \IT{intrinsic}, которая называется \IT{\_\_emul}\footnote{\url{https://msdn.microsoft.com/en-us/library/d2s81xt0(v=vs.80).aspx}} и еще одну: \IT{\_umul128}\footnote{\url{https://msdn.microsoft.com/library/3dayytw9%28v=vs.100%29.aspx}}.
GCC предлагает тип \IT{\_\_int128}, и если 64-битные множители вначале приводятся к 128-битным,
затем \glslink{product}{произведение} сохраняется в другой переменной \IT{\_\_int128}, затем результат сдвигается на 64 бита
право, вы получаете старшую часть результата\footnote{Например: \url{http://stackoverflow.com/a/13187798}}.

\subsubsection{Функция MulDiv() в Windows}
\myindex{Windows!Win32!MulDiv()}

В Windows есть ф-ция MulDiv()
\footnote{\url{https://msdn.microsoft.com/en-us/library/windows/desktop/aa383718(v=vs.85).aspx}},
это ф-ция производящая одновременно умножение и деление, она в начале перемножает два 32-битных числа и получает
промежуточное 64-битное значение, а затем делит его на третье 32-битное значение.
Это проще чем использовать две \IT{compiler intrinsic}, так что разработчики в Microsoft решили сделать специальную ф-цию
для этого.
И судя по использованию оной, она достаточно востребована.

